package com.ysu.his.dispensary.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ysu.his.dispensary.mapper.DrugDetailMapper;
import com.ysu.his.dispensary.mapper.DrugMapper;
import com.ysu.his.dispensary.mapper.PrescriptionItemMapper;
import com.ysu.his.dto.PrescriptionDto;
import com.ysu.his.entity.dispensary.DispenseRecord;
import com.ysu.his.entity.dispensary.RefundRecord;
import com.ysu.his.entity.drug.DrugDetail;
import com.ysu.his.entity.prescription.Prescription;
import com.ysu.his.entity.prescription.PrescriptionItem;
import com.ysu.his.utils.AuthContextUtil;
import com.ysu.his.vo.DispensingVo;
import com.ysu.his.vo.PrescriptionVo;
import com.ysu.his.vo.RefundVo;
import com.ysu.his.dispensary.mapper.PrescriptionMapper;
import com.ysu.his.dispensary.service.PrescriptionService;
import com.ysu.his.exception.HISException;
import com.ysu.his.vo.common.ResultCodeEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 处方相关业务实现类
 */
@Service
public class PrescriptionServiceImpl implements PrescriptionService
{

    @Autowired
    private PrescriptionMapper prescriptionMapper;

    @Autowired
    private PrescriptionItemMapper prescriptionItemMapper;

    @Autowired
    private DrugDetailMapper drugDetailMapper;

    @Override
    public PageInfo<Prescription> getPrescriptionByPage(Integer page, Integer limit, PrescriptionDto prescriptionDto)
    {

        PageHelper.startPage(page, limit);
        List<Prescription> list = prescriptionMapper.getPrescriptionByPage(prescriptionDto);
        list.forEach(prescription ->
        {
            List<PrescriptionItem> prescriptionItemList = null;
            try
            {
                prescriptionItemList = prescriptionItemMapper
                        .getPrescriptionItemByPrescriptionId(prescription.getId());
            } catch (Exception e)
            {
                e.printStackTrace();
            }

            prescription.setPrescriptionItemList(prescriptionItemList);
        });

        return new PageInfo<>(list);
    }

    @Override
    public PrescriptionVo getPrescriptionById(Long id)
    {
        PrescriptionVo prescriptionVo = prescriptionMapper.getPrescriptionVoById(id);

        List<PrescriptionItem> prescriptionItemList = prescriptionItemMapper
                .getPrescriptionItemByPrescriptionId(prescriptionVo.getId());

        prescriptionVo.setPrescriptionItemList(prescriptionItemList);

        if (prescriptionVo != null && prescriptionVo.getStatus() != null)
        {
            // 设置状态描述
            prescriptionVo.setStatusDesc(getStatusDesc(prescriptionVo.getStatus()));
        }
        return prescriptionVo;
    }

    @Override
    @Transactional
    public void dispensing(Long prescriptionId)
    {
        try
        {
            // 查询处方信息
            Prescription prescription = prescriptionMapper.getPrescriptionById(prescriptionId);

            if (prescription == null)
            {
                throw new HISException(ResultCodeEnum.PRESCRIPTION_NOT_EXIST);
            }

            // 检查处方状态是否为待发药
            if (prescription.getStatus() != 0)
            {
                throw new HISException(ResultCodeEnum.PRESCRIPTION_STATUS_ERROR);
            }

            // 创建发药记录
            DispenseRecord dispenseRecord = new DispenseRecord();
            dispenseRecord.setPrescriptionId(prescriptionId);
            dispenseRecord.setPatientId(prescription.getPatientId());
            dispenseRecord.setPharmacist(AuthContextUtil.get().getUserName());
            dispenseRecord.setDispenseTime(new Date());
            dispenseRecord.setTotalAmount(prescription.getTotalAmount());
            dispenseRecord.setCreateTime(new Date());

            // 插入发药记录
            int insertResult = prescriptionMapper.insertDispenseRecord(dispenseRecord);
            if (insertResult <= 0)
            {
                throw new HISException(ResultCodeEnum.DISPENSING_FAILED);
            }

            // 更新处方状态为已发药
            prescription.setStatus(1);
            int updateResult = prescriptionMapper.updatePrescriptionStatus(prescription);
            List<PrescriptionItem> prescriptionItemList = prescriptionItemMapper
                    .getPrescriptionItemByPrescriptionId(prescriptionId);

            if (updateResult <= 0)
            {
                throw new HISException(ResultCodeEnum.DISPENSING_FAILED);
            }

            prescriptionItemList.forEach(prescriptionItem ->
            {

                int result = drugDetailMapper.updateQuantity(prescriptionItem);
                if (result <= 0)
                {
                    throw new HISException(ResultCodeEnum.UPDATE_QUANTITY);
                }
            });
        } catch (HISException e)
        {
            throw e;
        } catch (Exception e)
        {
            e.printStackTrace();
            throw new HISException(ResultCodeEnum.DISPENSING_FAILED);
        }
    }

    @Override
    @Transactional
    public void apply4Refund(Long prescriptionId)
    {
        try
        {
            // 查询处方信息
            Prescription prescription = prescriptionMapper.getPrescriptionById(prescriptionId);
            List<PrescriptionItem> prescriptionItemList = prescriptionItemMapper
                    .getPrescriptionItemByPrescriptionId(prescriptionId);

            if (prescription == null)
            {
                throw new HISException(ResultCodeEnum.PRESCRIPTION_NOT_EXIST);
            }

            // 检查处方状态是否为已发药
            if (prescription.getStatus() != 1)
            {
                throw new HISException(ResultCodeEnum.PRESCRIPTION_STATUS_ERROR);
            }

            prescriptionItemList.forEach(prescriptionItem ->
            {

                // 创建退药申请记录
                RefundRecord refundRecord = new RefundRecord();
                BeanUtils.copyProperties(prescriptionItem, refundRecord);
                refundRecord.setRefundAmount(prescriptionItem.getAmount());
                refundRecord.setPatientId(prescription.getPatientId());
                refundRecord.setPharmacist(AuthContextUtil.get().getUserName());

                // 插入退药申请记录
                int insertResult = prescriptionMapper.insertRefundRecord(refundRecord);

                if (insertResult <= 0)
                {
                    throw new HISException(ResultCodeEnum.REFUND_APPLY_FAILED);
                }

                DrugDetail drugDetail = new DrugDetail();
                BeanUtils.copyProperties(prescriptionItem, drugDetail);
                int result = drugDetailMapper.AddQuantity(drugDetail);

                if (result <= 0)
                {
                    throw new HISException(ResultCodeEnum.UPDATE_QUANTITY);
                }
            });

            prescription.setStatus(2);
            int result = prescriptionMapper.updatePrescriptionStatus(prescription);
            if (result <=0)
            {
                throw new HISException(ResultCodeEnum.DRUG_OPERATION_FAILED);
            }
        } catch (HISException e)
        {
            throw e;
        } catch (Exception e)
        {
            e.printStackTrace();
            throw new HISException(ResultCodeEnum.REFUND_APPLY_FAILED);
        }
    }

    @Override
    @Transactional
    public void processRefund(Long id, RefundVo refundVo)
    {
        try
        {
            // 查询退药记录
            RefundRecord refundRecord = prescriptionMapper.getRefundRecordById(id);
            if (refundRecord == null)
            {
                throw new HISException(ResultCodeEnum.REFUND_PROCESS_FAILED);
            }

//            // 更新退药记录信息
//            refundRecord.setDrugId(refundVo.getDrugId());
//            refundRecord.setRefundQuantity(refundVo.getRefundQuantity());
//            refundRecord.setRefundAmount(refundVo.getRefundAmount());
//            refundRecord.setReason(refundVo.getReason());
//            refundRecord.setPharmacist(refundVo.getPharmacist());
//            refundRecord.setRefundTime(new Date());

            // 更新退药记录
            int updateResult = prescriptionMapper.updateRefundRecord(refundRecord);

            if (updateResult <= 0)
            {
                throw new HISException(ResultCodeEnum.REFUND_PROCESS_FAILED);
            }
        } catch (HISException e)
        {
            throw e;
        } catch (Exception e)
        {
            e.printStackTrace();
            throw new HISException(ResultCodeEnum.REFUND_PROCESS_FAILED);
        }
    }

    /**
     * 获取状态描述
     *
     * @param status 状态值
     * @return 状态描述
     */
    private String getStatusDesc(Integer status)
    {
        switch (status)
        {
            case 0:
                return "待发药";
            case 1:
                return "已发药";
            case 2:
                return "已取消";
            default:
                return "未知状态";
        }
    }
} 